Opakování části programu – cyklus

python.edumach.cz

Opakujeme provádění příkazů

import tkinter
from random import *

canvas = tkinter.Canvas()
canvas.pack()

canvas.create_text(randrange(400), randrange(300), text='1')
canvas.create_text(randrange(400), randrange(300), text='2')
canvas.create_text(randrange(400), randrange(300), text='3')
canvas.create_text(randrange(400), randrange(300), text='4')
canvas.create_text(randrange(400), randrange(300), text='5')

Všimněte si dalšího způsobu importu knihovny random. Když importujeme modul zápisem from random import *, nemusíme zapisovat název knihovny random.randrange(400), ale zapíšeme pouze randrange(400). Tento zápis znamená: „importujte vše z modulu random“.

Tento program postupně vypíše čísla 1, 2, 3, 4 a 5 na náhodném místě grafické plochy. Pokud bychom chtěli zapisovat čísla do 10, stačí příkaz k zápisu textu několikrát zkopírovat a postupně měnit zadaná čísla na 6, 7, 8, 9 a 10. Představme si, že bychom tímto způsobem chtěli zapsat až 50 čísel, to by už byl náš program velmi dlouhý a neustále bychom kopírovali příkazy. Existuje i jednodušší řešení. Chceme-li příkaz nebo sekvenci příkazů opakovat několikrát, můžeme použít for cyklus. Program píšeme takto:

import tkinter
from random import *

canvas = tkinter.Canvas()
canvas.pack()

for i in range(1,6):
    canvas.create_text(randrange(400), randrange(300), text='1')

Nyní program zopakuje příkaz create_text pětkrát a zatím pokaždé zapíše 1. Zápisem for i in range(1, 6): jsme definovali, že další část programu se bude opakovat a postupně si budeme pamatovat  čísla v závorkách v proměnné i, tj. 1 až 5. I když je tam zapsáno 1 až 6, pro hodnotu 6 se tělo cyklu nebude opakovat. Takto bude vypadat naše okno:

Pokud zápis text='1' nahradíme zápisem text=i, místo čísla 1 vypíšeme hodnotu v proměnné i, tedy postupně čísla 1 až 5.

for i in range(10,16):
    canvas.create_text(randrange(400), randrange(300), text=i)

❓Otázky

  1. Která čísla bude vypisovat výše uvedený program?

  2. Co bude dělat program, když text=i změníme na text='1'?

  3. Upravte program tak, aby vypisoval:
    a. čísla od 15 do 19 včetně,
    b. čtyři čísla od čísla 23.

  4. Zjistěte, která čísla vypíše program, když mu zadáte rozsah:
    a. range(50, 60),
    b. range(15, 16),
    c. range(10, 10),
    d. range(15, 10),
    e. range(5),
    f. range(3),
    g. range(-10, -5),
    h. range(-10, 3).

  5. Co bude dělat tento program:

    for i in range(20,25):
        print(i*10)
    

Porovnejte následující dva programy:

for  i in range(10,16):
    x = randint(0, 300)
    y = randint(0, 300)
    canvas.create_rectangle(x-10, y-10, x+10, y+10)
    canvas.create_text(x, y, text=i)
for i in range(10,16):
    x = randint(0, 300)
    y = randint(0, 300)
    canvas.create_rectangle(x-10, y-10, x+10, y+10)
canvas.create_text(x, y, text=i)

Při psaní cyklu for si musíme dát velký pozor na odsazení začátku řádku – mezeru na začátku. Ve smyčce for se opakují pouze příkazy, které jsou odsazeny stejným způsobem. Pokud má některý řádek méně mezer nebo text začíná hned na začátku řádku, program již tento příkaz umístí mimo smyčku, a proto se nebude opakovat. Druhý program už za nás poslední řádek neopakuje. Počítač rozumí zápisu tak, že tento řádek je již mimo smyčku. Proto nakreslí pět čtverečků, ukončí smyčku a teprve poté jednou provede příkaz create_text a vypíše aktuální hodnotu proměnné i, číslo 15.

For cyklem kreslíme obrázky s pravidelností

Zjistěte, co nakreslí tento program:

y = 0
for i in range(1,6):
    y = y + 10
    canvas.create_line(10, y, 200, y)

Před smyčkou nastavíme proměnnou y na nulu. Pak se smyčka bude opakovat postupně pro i s hodnotami 1, 2, 3, 4 a 5. Program pokaždé zvýší hodnotu proměnné y o deset, takže y bude mít postupně hodnoty 10, 20, 30, 40, 50 a pro tyto hodnoty bude pokaždé nakreslena vodorovná čára. Tato přímka má stejnou souřadnici y jako hodnota proměnné y a přímka začíná na souřadnici x 10 a končí na souřadnici x 200. V tomto případě se bude jednat o přímku, která bude mít stejnou souřadnici y jako hodnota proměnné y. Budeme-li postupně dosazovat hodnoty, které budou proměnné nabývat, budeme skutečně kreslit přímky s těmito hodnotami souřadnic.

canvas.create_line(10, 10, 200, 10)
canvas.create_line(10, 20, 200, 20)
canvas.create_line(10, 30, 200, 30)
canvas.create_line(10, 40, 200, 40)
canvas.create_line(10, 50, 200, 50)

Stejného efektu – vykreslení stejného výsledku – dosáhneme následujícími dvěma zápisy. Zamyslete se a zdůvodněte, proč i tyto programy vykreslují totéž.

for i in range(1,6):
    canvas.create_line(10, i*10, 200, i*10)
for i in range(10,60,10):
    canvas.create_line(10, i, 200, i)

V tomto programu jsme použili tři čísla v zápisu rozsahu. Třetí číslo slouží k určení kroku, o který se má změnit hodnota proměnné i. Pokud jej nezadáme jako dříve, krok se automaticky nastaví na hodnotu 1.

Smyčka for opakuje příkazy velmi rychle, takže výsledek vidíme hned. Pokud bychom chtěli vykreslování zpomalit, můžeme v cyklu použít příkaz canvas.after(1000). Tento příkaz zpozdí provádění programu o dobu uvedenou v závorce. Čas zadáváme v milisekundách, takže canvas.after(1000) počká 1 sekundu.

Kromě tohoto příkazu musíme použít příkaz canvas.update(), abychom zajistili aktualizaci grafického plátna i mezi jednotlivými čekáními. Kdybychom jej nepoužili, program by běžel pomaleji (s čekáním) a grafické plátno by se překreslovalo až po ukončení cyklu for. Hotový program zapíšeme následovně:

for i in range(1,6):
    canvas.create_line(10, i*10, 200, i*10)
    canvas.update()
    canvas.after(1000)

Do programu přidáme příkaz print(), abychom v příkazovém režimu (v okně shellu) viděli jednotlivé hodnoty y-ových souřadnic řádků.

for i in range(1,6):
    print(i*10)
    canvas.create_line(10, i*10, 200, i*10)
    canvas.update()
    canvas.after(1000)

💾 Úkoly

  1. Pokuste se vymyslet jiný zápis programu, který kreslí stejný obrázek jako tento program:
x = 0
for i in range(1,11):
    x = x + 20
    canvas.create_rectangle(x, 10, x+15, 20)
  1. Zkuste uhodnout, co nakreslí následující program:
x = 0
for i in range(1,11):
    x = x+20
    canvas.create_rectangle(x, 10, x+15, 20)
  1. Experimentujte s čísly v programu, abyste zjistili, jak změní nakreslený obrázek, a své postřehy zdůvodněte.
    a. Co se stane, když do řádku x = 0 zadáme jiné číslo?
    b. Co se stane, když do řádku x = x + 20 zadáme místo 20 jiné číslo?
    c. Co se stane, když v příkazu create_rectangle změníme číslo 15 na jiné?

  2. Experimentujte s původním programem a zkuste nakreslit tyto obrazce:

  3. Cyklem for nakreslete tyto obrazce:

  4. Program níže měl nakreslit tento obrazec, ale obsahuje chybu. Najděte ji a opravte:

    for i in range(10,16):
        y = 0
        canvas.create_rectangle(100, y, 200, y+10)
    
  5. Cyklem for nakreslete vedle sebe tři roboty z předchozí kapitoly:

  6. Pomocí cyklu for nakreslete otočený nápis “Python” (nebo jiné slovo):

  7. Pomocí cyklu for nakreslete schody:

  8. Pomocí cyklu for vypište do okna shellu:
    a) všechna sudá čísla od 20 do 40,
    b) všechna lichá čísla od 20 do 40.

  9. Pomocí cyklu for vypište do okna shellu:
    a) 1,2,4,8,16,32,64,128,256,5121, 2, 4, 8, 16, 32, 64, 128, 256, 512.
    b) 3,2,1,0,1,2,33, 2, 1, 0, -1, -2, -3.

  10. Tento program nakreslí obrázek v ukázce:

    import tkinter
    canvas = tkinter.Canvas(width=1000, height=800, bg='black')
    canvas.pack()
    
    x = 10
    y = 10
    for i in range(1,27):
        canvas.create_line(x, 10, 510, y, fill='white', width=2)
        canvas.update()
        canvas.after(100)
        x = x + 20
        y = y + 20
    

    Doplňte program tak, aby nakreslil i zbylé části obrázku:

  11. Nakreslete tyto vzory (bez použití create_text):